/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package controller;

import java.awt.AWTException;
import java.awt.Color;
import java.awt.Cursor;
import java.awt.Dimension;
import java.awt.Graphics2D;
import java.awt.GraphicsConfiguration;
import java.awt.GraphicsDevice;
import java.awt.GraphicsEnvironment;
import java.awt.Point;
import java.awt.Rectangle;
import java.awt.Robot;
import java.awt.Toolkit;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.net.URISyntaxException;
import java.sql.Connection;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.logging.Level;
import java.util.logging.Logger;
import java.util.prefs.BackingStoreException;

import view.PlayerCanvas;

import command.CommandFactory;

import model.Player;
import config.Debug;
import config.Helper;
import config.Settings;

/**
 * 
 * @author Yang Wang <yang@digitalmenubox.com>
 */
public class Command {
	// public static final COMMANDS

	/**
	 * Cause the application to restart
	 * 
	 * @return true if application is restarted.
	 */
	public static boolean restartApplication1() {
		Debug.msg("Restarting Player");
		Debug.log("The Player is restarted.", Debug.SYSTEM_LEVEL);
		File jarFile = null;
		try {
			System.out.println(Player.getInstance().getClass().getProtectionDomain().getCodeSource().getLocation().getPath());
			jarFile = new File(Player.getInstance().getClass().getProtectionDomain().getCodeSource().getLocation().toURI().getPath());
		} catch (URISyntaxException ex) {
			Logger.getLogger(Command.class.getName()).log(Level.SEVERE, null, ex);
		}
		try {
			String str = jarFile.toString();
			String path = "";
			int lastSlashIndex = str.lastIndexOf("/");
			if (lastSlashIndex >= 0) {
				path = str.substring(0, lastSlashIndex);
			}

			if (Helper.getPlatform() == Helper.LINUX_OS) {
				String cmd = "java -Xms256M -Xmx256M -jar dmbplayer.jar";
				Process p = Runtime.getRuntime().exec(cmd, null, jarFile.getParentFile());
			} else {
				String[] args = new String[] {
						"osascript",
						"-e",
						"do shell script \"ps ax | grep -i \\\"dmbplayer\\\" | grep -v grep | cut -c 1-6\"\nset pNum to result\ntry\ndo shell script \"kill -9 \" & pNum\nend try\ntell application \"dmbplayer\" to launch" };
				Process p = Runtime.getRuntime().exec(args);
			}
		} catch (IOException e) {
			Debug.log("Error while restarting application", Debug.ERROR_LEVEL);
			System.err.println("Error while restarting application");
		}

		System.exit(0);

		return true;
	}

	public BufferedImage getScreenshot() {
		int width = 0;
		int height = 0;
		Rectangle virtualBounds = new Rectangle();
		GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment();
		GraphicsDevice[] gs = ge.getScreenDevices();
		for (int j = 0; j < gs.length; j++) {
			GraphicsDevice gd = gs[j];
			GraphicsConfiguration[] gc = gd.getConfigurations();
			for (int i = 0; i < gc.length; i++) {
				virtualBounds = virtualBounds.union(gc[i].getBounds());
				width += virtualBounds.getWidth();
				height += virtualBounds.getHeight();
			}
		}

		try {
			Robot screenshotRobot = new Robot();
			screenshotRobot.createScreenCapture(new Rectangle(0, 0, width, height));
		} catch (AWTException e) {
			Debug.log("Error creating robot to take screenshot.");
		}
		return null;
	}

	/**
	 * This function will recursively delete files inside the given folder if
	 * the parameter passed in is a folder, otherwise it will delete the file
	 * 
	 * @param file
	 *            the file/folder to be deleted
	 * @return true if file has been successfully deleted
	 */
	public static boolean recursiveDeleteFile(File file) {
		if (file.isFile()) {
			System.out.println("Deleting " + file.getAbsolutePath());
			return file.delete();
		} else if (file.isDirectory()) {
			boolean result = true;
			for (File f : file.listFiles()) {
				result = result && recursiveDeleteFile(f);
			}
			if (file.listFiles().length == 0) {
				return file.delete();
			}
			return result;
		} else {
			return false;
		}
	}

	/**
	 * Drops all the tables used by the player
	 */
	public static void cleanDatabaseTable() {
		Connection conn = Settings.getLocalDatabaseConnection();
		if (conn == null) {
			// no database connection;
			// TODO: show message, unable to truncate table
			return;
		}
		Statement s = null;
		try {
			s = conn.createStatement();
			for (String tableName : Settings.MYSQL_PLAYER_TABLES) {
				s.execute("TRUNCATE TABLE " + tableName);
			}
		} catch (SQLException ex) {
			// TODO: handle sql exception
			Logger.getLogger(Helper.class.getName()).log(Level.SEVERE, null, ex);
		}
	}

	/**
	 * reset database and files for the player this function does not reset
	 * settings for the player
	 */
	public static void resetPlayer() {
		Debug.log("Player is reset to default.", Debug.SYSTEM_LEVEL);
		recursiveDeleteFile(new File(Settings.getResourceDirectory()));
		cleanDatabaseTable();
		Settings.save();
	}

	/**
	 * reset the configuration settings for the player to use the default
	 * settings.
	 */
	public static void resetSettings() {
		File settingsFile = new File(Settings.CONFIG_FILE);
		if (settingsFile.exists()) {
			boolean deleted = settingsFile.delete();
			System.out.println("deleted: " + deleted);
		}
	}

	public static void moveMouseToRightSide() {
		try {
			hideCursor();
			Robot robot = new Robot();
			robot.mouseMove(Helper.scale(Settings.getPlayerWidth() / 2), Helper.scale(Settings.getPlayerHeight() / 2));
			// Debug.log("Move Mouse " + Helper.scale(0) + " " +
			// Helper.scale(Settings.getPlayerHeight()), Debug.SYSTEM_LEVEL);
		} catch (AWTException ex) {
			Logger.getLogger(Command.class.getName()).log(Level.SEVERE, null, ex);
		}
	}

	public static void hideCursor() {
		Toolkit toolkit = Toolkit.getDefaultToolkit();

		// get the smallest valid cursor size
		Dimension dim = toolkit.getBestCursorSize(1, 1);

		// create a new image of that size with an alpha channel
		BufferedImage cursorImg = new BufferedImage(dim.width, dim.height, BufferedImage.TYPE_INT_ARGB);

		// get a Graphics2D object to draw to the image
		Graphics2D g2d = cursorImg.createGraphics();

		// set the background 'color' with 0 alpha and clear the image
		g2d.setBackground(new Color(0.0f, 0.0f, 0.0f, 0.0f));
		g2d.clearRect(0, 0, dim.width, dim.height);

		// dispose the Graphics2D object
		g2d.dispose();

		// now create your cursor using that transparent image
		Cursor hiddenCursor = toolkit.createCustomCursor(cursorImg, new Point(0, 0), "hiddenCursor");

		PlayerCanvas.getInstance().setCursor(hiddenCursor);
	}

	public static void upgradePlayer() {
		// Debug.log("upgrade player.", Debug.SYSTEM_LEVEL);
		FileInputStream fis = null;
		FileOutputStream fos = null;
		File dmbplayerJarFile = new File(Helper.getCurrentPath(), Settings.PLAYER_EXECUTABLE);
		// copy the new jar file over
		if (dmbplayerJarFile.exists()) {
			if (Helper.getPlatform() == Helper.MAC_OS) {
				File destinationDirectory = new File(Helper.getCurrentPath(), "dmbplayer.app/Contents/Resources/Java/dmbplayer.jar");
				try {
					fis = new FileInputStream(dmbplayerJarFile);
					fos = new FileOutputStream(destinationDirectory);
					byte[] data = new byte[(int) dmbplayerJarFile.length()];
					fis.read(data);
					fos.write(data);
				} catch (FileNotFoundException e) {
					Debug.log("FileNotFoundException occured in Command.upgradePlayer().", Debug.ERROR_LEVEL);
					throw new RuntimeException("This should never occur because we checked the file exists.", e);
				} catch (IOException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				} finally {
					try {
						if (fis != null)
							fis.close();
					} catch (IOException e1) {
					}
					try {
						if (fis != null)
							fos.close();
					} catch (IOException e) {
					}
				}
				// delete the current dmbplayer file
				// Debug.log("DELETE JAR", Debug.SYSTEM_LEVEL);
				dmbplayerJarFile.delete();
				Settings.save();
				CommandFactory.getInstance().restartPlayer();
			} else {
				// Other platforms
			}
		} else {
			// Debug.log("JAR FILE NOT EXISTS " +
			// dmbplayerJarFile.getAbsolutePath(), Debug.SYSTEM_LEVEL);
		}
		// Debug.log("DONE UPGRADING", Debug.SYSTEM_LEVEL);
	}
}